package base;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

// Representa um conjunto de soluções para o Problema do Caixeiro Viajante.
// Em um algoritmo genético, corresponde a uma população de cromossomos.
public class Populacao {

    private final List<Solucao> solucoes;
    private boolean melhorou;

    public Populacao() {
        solucoes = new ArrayList<>();
        melhorou = false;
    }

    public List<Solucao> getSolucoes() {
        return solucoes;
    }

    // Adiciona uma solução à população.
    public void adiciona(Solucao s) {
        solucoes.add(s);
        Collections.sort(solucoes);
    }

    // Retorna a melhor solução da população.
    // Ela está no índice 0 porque a população está ordenada pelo custo.
    public Solucao getMelhorElemento() {
        return solucoes.get(0);
    }

    // Retorna a pior solução da população.
    // Ela está no último índice porque a população está ordenada pelo custo.
    public Solucao getPiorElemento() {
        return solucoes.get(solucoes.size() - 1);
    }

    public boolean melhorou() {
        boolean retorno = melhorou;
        melhorou = false;
        return retorno;
    }

    // Atualiza a população para a próxima iteração, incluindo (ou não) cada um
    // dos filhos gerados, conforme sua aptidão.
    // Cada solução filha entra para a população se for melhor que a atual pior
    // solução da população, substituindo-a.
    // Ou seja, é usado o Steady State.
    public void atualizaParaProximaIteracao(ParDeSolucoes filhos) {
        entraSeForApto(filhos.getSolucao1());
        entraSeForApto(filhos.getSolucao2());
    }

    // Inclui a solução filho na população se tiver custo menor que a atual pior
    // solução da população.
    private void entraSeForApto(Solucao filho) {
        Solucao pior = getPiorElemento();

        if (filho.getCusto() < pior.getCusto()) {
            solucoes.remove(pior);
            adiciona(filho);
            melhorou = true;
        }
    }
}
